package com.blue.http.annotation;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;

import com.blue.core.util.BeanUtil;
import com.blue.core.util.UrlUtil;
import com.blue.http.invoke.InvokerFilter;

/**
 * HTTP 过滤器解析
 * 
 * @author zhengj
 * @since 1.0 2017年3月14日
 */
public class HttpFilterParser
{
	private static Logger logger = LoggerFactory.getLogger(HttpFilterParser.class);

	private ApplicationContext ctx;

	private Map<Class<?>, List<String>> filterCache = new HashMap<>();
	private Map<Class<?>, List<String>> excludeCache = new HashMap<>();
	private List<InvokerFilter> filterList = new ArrayList<>();

	public HttpFilterParser(ApplicationContext ctx)
	{
		this.ctx = ctx;
	}

	public List<InvokerFilter> allFilter()
	{
		return filterList;
	}

	public boolean match(Class<?> clazz, String url)
	{
		this.parse(clazz);
		
		List<String> excludeList = excludeCache.get(clazz);
		if (excludeList != null && !excludeList.isEmpty())
		{
			for (String tpl : excludeList)
			{
				if (UrlUtil.match(url, tpl))
					return false;
			}
		}
		
		List<String> urlList = filterCache.get(clazz);
		if (urlList == null || urlList.isEmpty())
			return false;

		for (String tpl : urlList)
		{
			if (UrlUtil.match(url, tpl))
				return true;
		}
		return false;
	}

	public void parse(Class<?> clazz)
	{
		if (filterCache.containsKey(clazz))
			return;

		if (!InvokerFilter.class.isAssignableFrom(clazz))
			throw new IllegalArgumentException(clazz.getName() + " 没有实现 InvokerFilter 接口");

		HttpFilter annoHttpFilter = clazz.getAnnotation(HttpFilter.class);
		if (annoHttpFilter == null)
			throw new IllegalArgumentException(clazz.getName() + " 缺少 @HttpFilter 注解");

		List<String> urlList = new ArrayList<>();
		for (String url : annoHttpFilter.value())
		{
			urlList.add(url);
		}
		filterCache.put(clazz, urlList);
		List<String> excludeList = new ArrayList<>();
		for (String url : annoHttpFilter.exclude())
		{
			excludeList.add(url);
		}
		excludeCache.put(clazz, excludeList);
		
		InvokerFilter filter = BeanUtil.initBean(clazz, InvokerFilter.class, ctx);
		filterList.add(filter);
		logger.info("找到 HttpFilter：{}，模式：{}，排除：{}", clazz.getName(), urlList, excludeList);
	}

}
